package com.owen.java.demo.gc;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 按照代码来看，主线程休眠 1000ms 后就会输出结果，但是实际情况却是主线程一直在等待 t1,t2 执行结束才继续执行。
 * 这个循环就属于前面说的可数循环（Counted Loop）。
 *
 * 这个程序发生了什么事情呢？
 *
 * 1.启动了两个长的、不间断的循环（内部没有安全点检查）。
 * 2.主线程进入睡眠状态 1 秒钟。
 * 3.在 1000 ms 之后，JVM 尝试在 Safepoint 停止，以便 Java 线程进行定期清理，但是直到可数循环完成后才能执行此操作。
 * 4.主线程的 Thread.sleep 方法从 native 返回，发现安全点操作正在进行中，于是把自己挂起，直到操作结束。
 * 所以，当我们把 int 修改为 long 后，程序就表现正常了（见 MainTest2），
 * 受到 RocketMQ 源码的启示，我们还可以直接把它的代码拿过来（见 MainTest3）。
 * https://mp.weixin.qq.com/s/cC_Lgyu3qUJDo7ib3flnKg
 */
public class MainTest1 {
    public static AtomicInteger num = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable=()->{
            for (int i = 0; i < 1000000000; i++) {
                num.getAndAdd(1);
            }
            System.out.println(Thread.currentThread().getName()+"执行结束!");
        };

        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        t1.start();
        t2.start();
        Thread.sleep(1000);
        System.out.println("num = " + num);
    }
}
